/**
 * (c) 2015-2020
 *
 * Author: zeyuphoenix
 *
 * License: www.blogjava.net/zeyuphoenix
 *
 * version: 1.0.0
 */

(function () {
    "use strict";

    var config = {
            /* define locations of mandatory javascript files */
            files: {
                JQUERY: 'jquery-1.11.0.js',
                ECHARTS: 'echarts.min.js',
                ECHARTS_THEME: 'macarons.js',
                ECHARTS_DATA: 'chartData.js'
            },
            THEME: 'macarons',
            TIMEOUT: 5000 /* 5 seconds timout for loading images */
        },
        mapCLArguments,
        render,
        startServer = false,
        stopServer = false,
        server,
        args,
        pick,
        system = require('system'),
        fs = require('fs'),
        serverMode = false;

    pick = function () {
        var args = arguments, i, arg, length = args.length;
        for (i = 0; i < length; i += 1) {
            arg = args[i];
            if (arg !== undefined && arg !== null && arg !== 'null' && arg != '0') {
                return arg;
            }
        }
    };

    mapCLArguments = function () {
        var map = {},
            i,
            key;

        if (system.args.length < 1) {
            console.log('Commandline Usage: run PhantomJS as server: echarts-convert.js -host 127.0.0.1 -port 1234');
        }

        for (i = 0; i < system.args.length; i += 1) {
            if (system.args[i].charAt(0) === '-') {
                key = system.args[i].substr(1, i.length);
                map[key] = system.args[i + 1];
            }
        }
        return map;
    };

    render = function (params, exitCallback) {

        var page = require('webpage').create(),
            createChart,
            width,
            height,
            border,
            padding,
            chartoptions,
            convert,
            exit;

        page.viewportSize = {
            width: 1440,
            height: 768
        };

        page.onConsoleMessage = function (msg) {
            console.log(msg);

            /*
             * Ugly hack, but only way to get messages out of the 'page.evaluate()'
             * sandbox. If any, please contribute with improvements on this!
             */
        };

        page.onAlert = function (msg) {
            console.log(msg);
        };

        exit = function (result) {
            if (serverMode) {
                //Calling page.close(), may stop the increasing heap allocation
                page.close();
            }
            exitCallback(result);
        };

        convert = function (svg) {
            var base64 = svg.split(",")[1];
            exit(base64);
        };

        createChart = function (width, height, border, padding, chartoptions) {

            var $container;

            // dynamic script insertion
            function loadScript(varStr, codeStr) {
                var $script = $('<script>').attr('type', 'text/javascript');
                $script.html('var ' + varStr + ' = ' + codeStr);
                document.getElementsByTagName("head")[0].appendChild($script[0]);
                if (window[varStr] !== undefined) {
                    console.log('echarts.' + varStr + '.parsed');
                }
            }

            $(document.body).css('margin', '0px');

            $container = $('<div>').appendTo(document.body);
            $container.attr('id', 'container');
            $container.css('width', width);
            $container.css('height', height);
            $container.css('border', border);
            $container.css('padding', padding);

            //general chart options
            chartoptions.databind = document.getElementById('container');
            //don't send request
            chartoptions.remote = false;
            if (chartoptions.config) {
                chartoptions.config.animation = false;
            } else {
                chartoptions.config = {};
                chartoptions.config.animation = false;
            }
            // 默认透明背景色,报表里会变黑
            chartoptions.config.backgroundColor = '#eee';

            //create chart data
            var chartdata = new ChartData(chartoptions);
            var chartConfig = chartdata.getChartConfig();
            // disable animations
            chartConfig.animation = false;

            //must use local chart options
            // var myChart = echarts.init(document.getElementById('container'));
            var myChart = chartdata.getChart();
            myChart.setOption(chartConfig);

            //timeout 10ms
            //wait onLoadFinished method
            console.info("Chart create is ok.");

            return myChart.getDataURL();
        };

        if (params.length < 1) {
            exit("Error: Insuficient parameters");
        } else {

            width = pick(params.width, '100%');
            height = pick(params.height, '400px');
            border = pick(params.border, '1px solid #ccc');
            padding = pick(params.padding, '30px');
            chartoptions = params.chartoptions;

            if (chartoptions === undefined || chartoptions.length === 0) {
                exit('Error: Insuficient or wrong parameters for rendering');
            }

            page.open('about:blank', function (status) {
                var jsfile,
                    svg;

                // We have a js file, let echarts create the chart first and grab the image
                if (status == 'success') {
                    console.log("Phantom path " + phantom.libraryPath);

                    // load necessary libraries
                    for (jsfile in config.files) {

                        if (config.files.hasOwnProperty(jsfile)) {


                            // first check if the path exists, otherwise assume the file to be in the libaryPath
                            var relpath = config.files[jsfile];
                            if (!fs.exists(relpath)) {
                                relpath = phantom.libraryPath + fs.separator + relpath;
                            }
                            console.log("jsfile path " + relpath);

                            page.injectJs(relpath);
                        }
                    }

                    // load chart in page and return svg height and width
                    svg = page.evaluate(createChart, width, height, border, padding, chartoptions);

                    convert(svg);
                }
            });
        }
    };

    startServer = function (host, port) {

        if (startServer == true) {
            console.log("Phantom server is start!");
            return;
        }

        server = require('webserver').create();

        server.onConsoleMessage = function (msg) {
            console.log(msg);
        };

        server.listen(host + ':' + port,
            function (request, response) {
                //console.log(JSON.stringify(request, null));
                var info;
                var params = request.post,
                    msg;
                try {

                    //params = JSON.parse(jsonStr);
                    //console.log("cc:" + JSON.stringify(params, null));
                    //var test = '{"height":"400px","width":"1000px","chartoptions":{"remote":false,"type":"line","datas":{"xAxis":["一月","二月","三月","四月","五月","六月","七月","八月","九月"],"series":[[120,232,301000000,434,390,53000000,32000000,120,250],[150,100060,100090,150,2000032,20000001,1000054,390,10000010]],"min":[],"max":[]},"tilte":"用户流量趋势图","stack":false,"area":false,"name":"","radius":false,"legends":["上行流量","下行流量"],"formatType":"package"},"padding":"25px","border":"1px solid #ccc"}'
                    //var test = '{"status" :"isok"}';
                    //console.info(test);
                    //console.log(JSON.parse(test));
                    //console.log( JSON.stringify(request, null));
                    //console.log(request.post.body);
                    //console.log( test)
                    //params = JSON.parse(request.post.body)
                    //console.log(eval(request.post.body));

                    //接口改变，验证这种可用
                    params = JSON.parse(eval(request.post.body));
                    if (params.status) {
                        // for server health validation
                        response.statusCode = 200;
                        response.write('OK');
                        response.close();
                    } else {
                        render(params, function (result) {
                            response.statusCode = 200;
                            response.write(result);
                            response.close();
                        });
                    }
                } catch (e) {
                    msg = "Failed rendering: \n" + request + e;
                    response.statusCode = 500;
                    response.setHeader('Content-Type', 'text/plain');
                    response.setHeader('Content-Length', msg.length);
                    response.write(msg);
                    response.close();
                }
            }); // end server.listen

        // switch to serverMode
        serverMode = true;
        startServer = true;

        console.log("OK, PhantomJS is ready.");
    };

    stopServer = function (host, port) {

        if (startServer == false) {
            console.log("Phantom server is stop!");
            return;
        }
        if (server) {
        	server.close();
        }
        // switch to serverMode
        serverMode = false;
        startServer = false;

        console.log("OK, PhantomJS is stop.");
    };
    
    args = mapCLArguments();

    if (args.host !== undefined && args.port !== undefined) {
        startServer(args.host, args.port);
    } else {
        //error host or port
        console.log('ERROR: Error host or port, server not start');
    }
}());
